/*****************************************************************************
*    Ali Corp. All Rights Reserved. 2007 Copyright (C)
*
*    File:    slot.S
*
*    Description:    This file contains all code in standby mode.
*    History:
*           Date            Athor        Version          Reason
*	    ============	=============	=========	=================
*	1.	12.29.2007       Trueve Hu      Ver 0.1    Create file.
*****************************************************************************/
#include <hal/mips.h>
#include <hld/pan/pan.h>

#define CONFIGDATA_BASE 0xAFC00000
#define CRYSTAL_TYPE	0 

#define STBY_PAN_TYPE  0x01  

#ifdef _BOARD_DB_C3047_T2_01V01_
#define PAN_KEY_NUM	0x1 
#define PAN_KEY_NUM_MASK	0x70
#define IRP_KEY_NUM	2 
#define IRP_KEY_NUM_MASK	0x0F
#define IRP_KEY_STANDBY1	0x60df708f//(CONFIGDATA_BASE+0x160)	# 32bits.
#define IRP_KEY_STANDBY2	0x00fd9a65//(CONFIGDATA_BASE+0x164)	# 32bits.
#define IRP_KEY_STANDBY3	0x807fc03f//(CONFIGDATA_BASE+0x168)	# 32bits.
#define IRP_KEY_STANDBY4	0x60df708f//(CONFIGDATA_BASE+0x16C)	# 32bits.
#define PAN_KEY_STANDBY1	0x00000100//(CONFIGDATA_BASE+0x170)	# 32bits.
#define PAN_KEY_STANDBY2	0x00020000//(CONFIGDATA_BASE+0x174)	# 32bits.
#define PAN_KEY_STANDBY3	0x00000800//(CONFIGDATA_BASE+0x178)	# 32bits.
#define PAN_KEY_STANDBY4	0xfffffff0//(CONFIGDATA_BASE+0x17C)	# 32bits.

#define PAN_KEY_POWER_GPIO    24
#define PAN_KEY_POWER_GPIO_POL 0

#else
#define PAN_KEY_NUM	0x1 
#define PAN_KEY_NUM_MASK	0x70
#define IRP_KEY_NUM	0 
#define IRP_KEY_NUM_MASK	0x0F
#define IRP_KEY_STANDBY1		0x404050af//(CONFIGDATA_BASE+0x160)	# 32bits.
#define IRP_KEY_STANDBY2		0x404050af//(CONFIGDATA_BASE+0x164)	# 32bits.
#define IRP_KEY_STANDBY3		0x404050af//(CONFIGDATA_BASE+0x168)	# 32bits.
#define IRP_KEY_STANDBY4		0x404050af//(CONFIGDATA_BASE+0x16C)	# 32bits.
#define PAN_KEY_STANDBY1	0x02000000//(CONFIGDATA_BASE+0x170)	# 32bits.
#define PAN_KEY_STANDBY2	0xfffffff0//(CONFIGDATA_BASE+0x174)	# 32bits.
#define PAN_KEY_STANDBY3	0xfffffff0//(CONFIGDATA_BASE+0x178)	# 32bits.
#define PAN_KEY_STANDBY4	0xfffffff0//(CONFIGDATA_BASE+0x17C)	# 32bits.
#endif

#define HAL_GPIO_I_DIR			0
#define HAL_GPIO_O_DIR			1
#define GPIO_REG_ARRAY_SIZE		5	// refer to gpio_dir_reg_array[], etc.


# MACRO: bin2ascii(reg b1, reg d1)
#  reg b1: Input binary data.
#  reg d1: Output BCD code data.
# Internal:
#  t0: ;
#  t1: Primary higher 4 digital;
#  t2: Lower 4 bit digital;
#  t3: ;
#
		.macro	bin2ascii b1,d1
		andi	t0, \b1, 0xf0;
		srl		t0, 4;					# 6bits->2bits higher
		srl		t1, t0, 1;
		addu	t1, t0;					# Get the base: 00b=>0d, 01b=>1d, 10b=>3d, 11b=>4d
		sll		t2, t1, 3;
		sll		t3, t1, 1;
		addu	t3, t2;					# 10X: 0=>0, 1=>10, 2=>20, etc...
		subu	t2, \b1, t3;			# Get draft lower value to t2
		li		t0, 10;
		blt		t2, t0, 91f;			# If lower 4bits<10, finished
		nop
		addiu	t1, 1;					# Else higher+1, and lower-10.
		sub		t2, t0;
		blt		t2, t0, 91f;			# If lower 4bits<10, finished
		nop
		addiu	t1, 1;					# Else higher+1, and lower-10.
		sub		t2, t0;
91:		sll		t1, 4;
		or		\d1, t1, t2;
		.endm

# MACRO: get_led_array(reg dr)
#  reg dr: load led_array to dr.
#
		.macro	get_led_array dr
		la		\dr, led_array
		.endm

# MACRO: get_ir_power_key_num(reg dr)
#  reg dr: load ir power key number to dr.
#
		.macro	get_ir_power_key_num dr
		lb		\dr, IRP_KEY_NUM
		andi		\dr, IRP_KEY_NUM_MASK
		.endm

# MACRO: get_fp_power_key_num(reg dr)
#  reg dr: load fp power key number to dr.
#
		.macro	get_fp_power_key_num dr
		li		\dr, PAN_KEY_NUM
#		andi		\dr, PAN_KEY_NUM_MASK
		.endm
				
# MACRO: get_ir_power_key(reg dr, reg index)
#  reg dr: load No. index ir power key to dr.
#
		.macro	get_ir_power_key dr, index
		beq		\index, 0, 90f
		nop
		beq		\index, 1, 91f
		nop
		beq		\index, 2, 92f
		nop
93:
		li		\dr, IRP_KEY_STANDBY4	# get ir standby key 4
		b		99f
		nop
92:
		li		\dr, IRP_KEY_STANDBY3	# get ir standby key 3
		b		99f
		nop
91:
		li		\dr, IRP_KEY_STANDBY2	# get ir standby key 2
		b		99f
		nop
90:		
		li		\dr, IRP_KEY_STANDBY1	# get ir standby key 1
99:		
		.endm
		
# MACRO: get_fp_power_key(reg dr, reg index)
#  reg dr: load No. index fp power key to dr.
#
		.macro	get_fp_power_key dr, index
		beq		\index, 0, 90f
		nop
		beq		\index, 1, 91f
		nop
		beq		\index, 2, 92f
		nop
93:
		li		\dr, PAN_KEY_STANDBY4	# get pan standby key 4
		b		99f
		nop		
92:		
		li		\dr, PAN_KEY_STANDBY3	# get pan standby key 3
		b		99f
		nop		
91:		
		li		\dr, PAN_KEY_STANDBY2	# get pan standby key 2
		b		99f
		nop		
90:
		li		\dr, PAN_KEY_STANDBY1	# get pan standby key 1
99:
		.endm


# MACRO: get_pan_hw_info(reg dr)
#  reg dr: load pan_hw_info to dr.
#
		.macro	get_pan_hw_info dr
		la		\dr, pan_hw_info
		.endm

# MACRO: gettimerdata(reg sr)
#  reg dr: get timefield to dr
#
		.macro	gettimerdata dr
		li		t1, 0x80000700
		lw		\dr, 0(t1)
		.endm

# MACRO: settimerdata(reg sr)
#  reg dr: set sr(time) to  timefield.
#
		.macro	settimerdata sr
		li		t1, 0x80000700
		sw		\sr,0(t1)	
		.endm

# MACRO: getrepeatkeycnt(reg sr)
#  reg dr: get repeat key count to dr
#
		.macro	getrepeatkeycnt dr
		li		t1, 0x80000704
		lw		\dr, 0(t1)
		.endm

# MACRO: setrepeatkeycnt(reg sr)
#  reg dr: set repeat key count
#
		.macro	setrepeatkeycnt sr
		li		t1, 0x80000704
		sw		\sr,0(t1)	
		.endm

# MACRO: getrepeatkeycode(reg sr)
#  reg dr: get repeat key code to dr
#
		.macro	getrepeatkeycode dr
		li		t1, 0x80000708
		lw		\dr, 0(t1)
		.endm

# MACRO: setrepeatkeycode(reg sr)
#  reg dr: set repeat key code
#
		.macro	setrepeatkeycode sr
		li		t1, 0x80000708
		sw		\sr,0(t1)	
		.endm
		
# MACRO: get_pan_type(reg dr)
#  reg dr: load pan_type to dr.
#
#		.macro	get_pan_type dr
#		lb		\dr, PAN_TYPE
#		andi		\dr, PAN_TYPE_MASK
#		srl		\dr, 5
#		.endm

# MACRO: gettimercompare1s(reg dr)
#  reg dr: Output 1s.
	.macro	gettimercompare1s dr
		li		\dr, CRYSTAL_TYPE		# check crystal
		beq		\dr, 1, 91f 	# 13M crystal
		nop
		beq		\dr, 2, 92f	# 28.8M crystal
		nop
		li		\dr,  6750000			# (27000000/4)
		b		93f
		nop
91:
		li		\dr, 421875			# (13500000/32)
		b 		93f
		nop
92:
		li		\dr,  900000			# (28800000/32)
93:
	.endm


# ------------------------------------------------------------------------------
# void hal_gpio_set_dir(pos, dir)
#
# input:
#	a0: gpio pos
#   a1: gpio dir
#
# used:
#	t0: dir reg addr
#	t1
#	t2
# ------------------------------------------------------------------------------
        .globl  hal_gpio_set_dir
        .ent    hal_gpio_set_dir
   		.set	noreorder
hal_gpio_set_dir:
		srl		t1, a0, 5		# t1: index in gpio_dir_reg_array[]
		li		t2, GPIO_REG_ARRAY_SIZE
		bgeu	t1, t2, 1f
		nop
		
		la		t2, gpio_dir_reg_array
		sll		t1, t1, 1
		addu	t1, t2, t1		# t1: &gpio_dir_reg_array[index]

		lhu		t2, 0(t1)		# t2: gpio_dir_reg_array[index]
		lui		t0, 0xb800
		addu	t0, t0, t2		# t0: dir reg addr
		
		andi	a0, 0x1f
        lw      t1, 0(t0)		# t1: dir register
        li      t2, 1
        sll		t2, t2, a0		# t2: bit mask
        
		not		t2, t2			# clean bit
		and		t1, t1, t2

		andi	a1, 1			# set bit
		sll		a1, a1, a0
        or      t1, t1, a1
        sw      t1, 0(t0)
        nop
1:
        jr      ra
        nop
   		.set 	reorder
        .end    hal_gpio_set_dir

# ------------------------------------------------------------------------------
# void hal_gpio_set_bit(pos, val)
#
# input:
#	a0: gpio pos
#	a1: gpio val
#
# used:
#	t0: output reg addr
#	t1
#	t2
# ------------------------------------------------------------------------------
        .globl  hal_gpio_set_bit
        .ent    hal_gpio_set_bit
   		.set	noreorder
hal_gpio_set_bit:
		srl		t1, a0, 5		# t1: index in gpio_do_reg_array[]
		li		t2, GPIO_REG_ARRAY_SIZE
		bgeu	t1, t2, 1f
		nop
		
		la		t2, gpio_do_reg_array
		sll		t1, t1, 1
		addu	t1, t2, t1		# t1: &gpio_do_reg_array[index]

		lhu		t2, 0(t1)		# t2: gpio_do_reg_array[index]
		lui		t0, 0xb800
		addu	t0, t0, t2		# t0: output reg addr

		andi	a0, 0x1f
        lw      t1, 0(t0)		# t1: output register
        li      t2, 1
        sll		t2, t2, a0		# t2: bit mask
        
		not		t2, t2			# clean bit
		and		t1, t1, t2

		andi	a1, 1			# set bit
		sll		a1, a1, a0
        or      t1, t1, a1
        sw      t1, 0(t0)
        nop
1:
        jr      ra
        nop
        .set 	reorder
        .end    hal_gpio_set_bit

# ------------------------------------------------------------------------------
# void hal_gpio_get_bit(pos, val)
#
# input:
#	a0: gpio pos
#	a1: gpio polar
#
# used:
#	t0
#	t1
#	t2
#
# output:
#	v0: 1:status == polar; 0:status != polar
# ------------------------------------------------------------------------------
        .globl  hal_gpio_get_bit
        .ent    hal_gpio_get_bit
   		.set	noreorder
hal_gpio_get_bit:
        li      v0, 0           # v0: default = 0
        
		srl		t1, a0, 5		# t1: index in gpio_di_reg_array[]
		li		t2, GPIO_REG_ARRAY_SIZE
		bgeu	t1, t2, 1f
		nop
		
		la		t2, gpio_di_reg_array
		sll		t1, t1, 1
		addu	t1, t2, t1		# t1: &gpio_di_reg_array[index]

		lhu		t2, 0(t1)		# t2: gpio_di_reg_array[index]
		lui		t0, 0xb800
		addu	t0, t0, t2		# t0: input reg addr

		andi	a0, 0x1f
        lw      t1, 0(t0)		# t1: input register
        li      t2, 1
        sll		t2, t2, a0		# t2: bit mask
        
		and		t1, t1, t2
		beq		t1, zero, 2f 
		nop
		
        li      t1, 1
2:                              # t1: 0:low, 1:high 
		beq		t1, a1, 3f
		nop
		
        li      v0, 0           # v0: 0:status != polar
		b       1f
		nop
3: 
        li      v0, 1           # v0: 1:status == polar
		
#---------------------------------------		

1:
        jr      ra
        nop
        .set 	reorder
        .end    hal_gpio_get_bit



#ifdef _BOARD_DB_C3047_T2_01V01_
# ------------------------------------------------------------------------------
# void antenna_short_detect(void)
#
# input:
#
# used:
#	a0: gpio pos
#	a1: gpio polar
#	t0
#	t1
#	t2
#   t4: reserve ra
#
# output:
#	v0: 1:antenna is short,and turn off antenna power; 
#       0:antenna is normal, or power off
# ------------------------------------------------------------------------------
		.globl  antenna_short_detect
		.ent	antenna_short_detect
		.set 	noreorder
antenna_short_detect:
		move	t4, ra							# t4: save ra

		li		a0, PAN_KEY_POWER_GPIO		    # a0: gpio pos
		jal 	hal_gpio_set_dir			    # set gpio dir
		li		a1, HAL_GPIO_I_DIR			    # a1: gpio dir

		li		a0, PAN_KEY_POWER_GPIO		    # a0: gpio pos
		jal		hal_gpio_get_bit				# get gpio status
		li		a1, PAN_KEY_POWER_GPIO_POL       # a1: active polarity

		beq		v0, 1, get_pan_power_key      # antenna power is on now.
		nop
		beq		v0, 0, 1f                       # antenna power is off now, do nothing.
		nop
				
1:
		move	ra, t4

		jr		ra
		nop
		.set 	reorder
		.end	antenna_short_detect
#endif


#--------------------------------------------------------------------
#
#   Function_Name: sys_preboot
#     This function used only for board dedicat issue patch, just as
#     turn off LED GPIO, if you want do other patch about chipset,
#     please added into _Init_Chipset in boot.S.
#--------------------------------------------------------------------
		.globl  sys_preboot
		.ent	sys_preboot
		.set noreorder
sys_preboot:
		jr		ra
		nop
		.set 	reorder
		.end	sys_preboot

		.globl  sys_postboot
		.ent	sys_postboot
		.set noreorder
sys_postboot:
		jr		ra
		nop
		.set 	reorder
		.end	sys_postboot
				
#--------------------------------------------------------------------
#   Function_Name: sys_get_pinconfig(int chiptype)
#     This function used only for costomer to read in strap pins 
#     config, and do some further config according it.
#	chiptype =	1 : M3329
#							2 : M3329C		
#	Returns: v0: strap pin soft-control info
#					bit2: mem control 	0: disable, 1: enable
#					bit1: mem clock: 	0: 135M, 1: 120M
#					bit0: mem size:		0: 8MB, 1: 16MB
#--------------------------------------------------------------------
		.globl  sys_get_pinconfig
		.ent	sys_get_pinconfig
		.set noreorder		
sys_get_pinconfig:
		jr		ra
		nop				
		.set 	reorder
		.end	sys_get_pinconfig
		
		.globl  sys_prestandby
		.ent	sys_prestandby
		.set	noreorder
sys_prestandby:
		move		k0, ra
		nop
		jal		ini_ir					# Init IR
		nop
		nop 
		get_pan_hw_info a0
		jal		pan_init_sm1668				# Init pan
		nop	
		nop
		nop
		li		t1, STBY_PAN_TYPE		
		beq		t1, 0, 0f			# 0--show "----"	
		nop
		beq		t1, 1, 1f			# 1--show timer
		nop
		beq		t1, 2, 2f			# 2--show "off "
		nop
		beq		t1, 3, 3f			# 3--show blank
		nop
		b		5f
		nop
0:
		li		s6, 0xdddd			# "----" index
		b		5f
		nop
1:
		li		t0, (0x1f<<12)			# Hour in ASCII
		and 	v0, t0, s5
		srl 	v0, 12
		bin2ascii v0, t5
		sll 	t5, 8
		li		t0,(0x3f<<6)			# Minute in ASCII
		and 	v0, t0, s5
		srl 	v0, 6
		bin2ascii v0, t4
		or		s6, t4, t5		
		settimerdata s6
		b		5f
		nop
2:
		li		s6, 0xabbf				# "OFF " index
		b		5f
		nop
3:
		li		s6, 0xffff				# "    " index
5:
		move		ra, k0
		jr		ra
		nop
		.end sys_prestandby


		.globl	sys_poststandby
		.ent	sys_poststandby
		.set noreorder
sys_poststandby:
		jr		ra
		nop
		.set reorder
		.end sys_poststandby


		.globl	sys_standby_process
		.ent	sys_standby_process
		.set	noreorder
sys_standby_process:
#ifdef _BOARD_DB_C3047_T2_01V01_
        move    t7,ra
        jal     antenna_short_detect
        nop
        move    ra,t7
        nop
 #endif
		mfc0	t0, C0_COUNT			# Check scan or not
		nop  
		nop 			
		gettimercompare1s	t1
		srl	t1, 8				# 1/256 second per LED
		subu	t2, s4, t0
		bgtu	t2, t1, real_scan
		nop
		nop	
		li		v0,0
		nop
		jr		ra
		nop
real_scan:
		addu	s4, t1					# 1/256 second per LED
		move	k0, ra
		
		li		t1, STBY_PAN_TYPE
		bne		t1, 1, 1f			# if not show time, jump to 1f
		nop
		
		gettimerdata	t0
		move		s6, t0
1:				
# We just display one LED each times, keeping show when exit functionf
		sll		s6, 8					# s6[31:24] is the LED ID register
		srl		s6, 8
		nop 
#		nop 
#		sdbbp
#		nop 
		nop 			
		get_pan_hw_info a0		
		jal		check_key_sm1668
		nop

## if invalid key, jump to 7f show led
		li		t0, PAN_KEY_INVALID
		li		t2, 0	
		li		t3, 0
		beq		t0, v0, 7f
		nop
111:
        nop
        nop
        nop
        nop
        nop
# check repeat key code	
		getrepeatkeycnt	t2			# t2: key cnt
		nop
		b	check_pan_power_key
		nop
		nop 
## if(cnt==0), cnt++, jump to 5f save cnt & code
		beqz		t2, 5f
		nop
## if(new code != old code), cnt=1, jump to 5f save cnt & code
		getrepeatkeycode t3			# t3: key code
		move		t1, t3
		bne		t1, v0, 5f
		move		t3, v0

## if(++cnt<3), jump to 6f		
		addi		t2, 1
		li		t0, 2
		
		bltu		t2, t0, 6f
		nop

# get a real key
		li		t2, 0
		setrepeatkeycnt	t2			#reset key cnt	
			
		get_fp_power_key_num	t2
check_pan_power_key:	
		li		t2, 0
		nop 			
		get_fp_power_key t0, t2 			# Check power on key
		nop
		nop 
		nop 
#		sdbbp
		nop 		
		nop 			
		beq 	t0, v0, get_pan_power_key
		nop
		b 7f
		nop
		nop 
get_pan_power_key:
#ifdef _BOARD_DB_C3047_T2_01V01_
		get_pan_hw_info a0
		get_led_array a1
		li		a3,0
		li		s6,0xffff
		jal		show_led_sm1668
		nop
#endif
		li		s8, 0xdeadbead			# Set the flag about time to REF
		jal 		exit_standby			# Power key press, exit standby
		nop
		
5:
		li		t2, 1
7:	
		setrepeatkeycode t3			# save key code
6:		
		setrepeatkeycnt	t2			# save key cnt

1:		
		nop 
		nop 
#		sdbbp
		nop 
		nop 	
		get_pan_hw_info a0
		get_led_array	a1
#ifdef _BOARD_DB_C3047_T2_01V01_
		li		a3,1
#endif
		jal		show_led_sm1668
		nop

		move		ra, k0
		jr		ra
		nop
		.set reorder
		.end sys_standby_process


#define SYS_IC_NB_BASE_H		0xb800
#define SYS_IC_NB_EISR			0x30
#define SYS_IC_SB_IRC_BITIE 	0x80000

		.globl	sys_standby_exception
		.ent	sys_standby_exception
sys_standby_exception:	
		.set	noreorder
		la		t1, 3f					# Running in cache
		sll 	t1, 4
		srl 	t1, 4
		lui 	t0, 0x8000
		or		t1, t0
		jr		t1
		nop		
3:
		lui 	t1,SYS_IC_NB_BASE_H
		lw		t2,SYS_IC_NB_EISR(t1)
		li		t0, SYS_IC_SB_IRC_BITIE
		and 	t3,t2,t0				# IR interrupt?
		bnez	t3,2f
		nop
		
		li		s8, 0xdeadbeef			# Set the flag about enter IC stanby again
		jal 	exit_standby
		nop
2:
		jal 	get_ir					# Get IR code
		nop
		nop
		nop	
## if invalid key, jump to 4f
		li		t0, 0
		beq		t0, v0, 4f
		nop	
check_ir_power_key:	
#		get_ir_power_key	t0, t2			# Check POWER remote key code	
		li		t0, IRP_KEY_STANDBY1
		bne 	v0, t0, 4f
		nop
		nop
		nop
#		sdbbp
		nop 
		nop 
#ifdef _BOARD_DB_C3047_T2_01V01_
		get_pan_hw_info a0
		get_led_array a1
		li		a3,0
		li		s6,0xffff
		jal		show_led_sm1668
		nop
#endif
		li		s8, 0xdeadbead			# Set the flag about time to REF
		jal 	exit_standby
		nop
4:
		nop
		.set mips3
		eret
		.set mips1
		nop
		nop
		.set reorder
		.end sys_standby_exception

led_array:
#ifdef _BOARD_DB_C3047_T2_01V01_
			 /*  '0'   '1'   '2'   '3'*/
		.byte	0x3F, 0x06, 0x6B, 0x4F
			 /*  '4'   '5'   '6'   '7'*/
		.byte	0x56, 0x5D, 0x7D, 0x07
			 /*  '8'   '9'   'O'   'F'*/
		.byte	0x7F, 0x5F, 0x3F, 0x71
			 /*  ':'   '-'   '_'   ' '*/
		.byte	0x80, 0x40, 0x08, 0x00
#else
			 /*  '0'   '1'   '2'   '3'*/
		.byte	0x3F, 0x06, 0x5B, 0x4F
			 /*  '4'   '5'   '6'   '7'*/
		.byte	0x66, 0x6D, 0x7D, 0x07
			 /*  '8'   '9'   'O'   'F'*/
		.byte	0x7F, 0x6F, 0x3F, 0x71
			 /*  ':'   '-'   '_'   ' '*/
		.byte	0x01, 0x40, 0x08, 0x00
#endif
		
gpio_dir_reg_array:
		.half	0x0058, 0x00d8, 0x00f8, 0x0358, 0x0458

gpio_di_reg_array:
		.half	0x0050, 0x00d0, 0x00f0, 0x0350, 0x0450

gpio_do_reg_array:
		.half	0x0054, 0x00d4, 0x00f4, 0x0354, 0x0454
		
		
		
